package com.libs.utils;

import net.sourceforge.tess4j.Tesseract;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.impl.client.CloseableHttpClient;

import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.*;
import java.util.Random;

public class TestImgV1 {
    /**
     * tessdata 路径
     */
    private static final String TESSDATA_PATH = "G:\\project\\\\testdata\\\\tessdata";
//    private static final String TESSDATA_PATH = "..\\..\\..\\..\\..\\..\\project\\testdata\\tessdata";
    /**
     * 验证码图片地址
     */
    private static final String url = "https://lib-seat.chu.edu.cn/ClientWeb/pro/page/image.aspx?";

    public static void main(String[] args) throws Exception {
//        BufferedImage codeImage = ImageIO.read(new URL(url));
//
//        CloseableHttpClient httpClient = HttpClientConn.getHttpClient();
//        CloseableHttpResponse getRes = HttpClientConn.getGetRes(url, false, httpClient);
//        final InputStream content = getRes.getEntity().getContent();
//        BufferedImage codeImage = ImageIO.read(ImageIO.createImageInputStream(content));
//        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
//        ImageIO.write(codeImage, "JPEG", outputStream);
//        ImageIO.write(cleanColor(codeImage.getSubimage(6, 4, 48, 15)), "JPEG", outputStream);
//
//        // 本地做个备份，好对比
//        write2disk(codeImage);
//
//        Tesseract tessreact = new Tesseract();
//        tessreact.setDatapath(TESSDATA_PATH);
//
//        String result = tessreact.doOCR();
//        String res = result.replace(" ", "").trim();
//        System.out.println("测验结果：[" + result.replace(" ", "").trim() + "]");
//        LibService libService = new com.libs.sys.service.impl.LibServiceImpl();
//        System.out.println(libService.login(new Userseat("18037110","070010","100455730"),res,httpClient));


//        CloseableHttpClient httpClient = HttpClientConn.getHttpClient();
//        TestImgV1 testImgV1 = new TestImgV1();
//        final String number = getNumber(httpClient,true);
//        LibService libService = new LibServiceImpl();
//        System.out.println();
//        int n=1;
//        while("-1".equals(libService.login(new Userseat("18037110", "070010", "100455730"), httpClient))) {
//            n++;
//        }
//        System.out.println(n);

//        Tesseract tessreact = new Tesseract();
//        String result = tessreact.doOCR(new File("G:\\project\\libs\\src\\main\\resources\\img\\1.jpeg"));
//        String res = result.replace(" ", "").trim();
//        System.out.println(res);
//        test();
        CloseableHttpClient httpClientConn = HttpClientConn.getHttpClient();
        test(httpClientConn,true);

    }

    private static void write2disk(BufferedImage image, String name) throws IOException {
        File file = new File("G:\\project\\libs\\src\\main\\resources\\img\\" + name + ".jpg");
        ImageIO.write(image, "jpg", file);
    }

    public static String getNumber(CloseableHttpClient httpClient, boolean islogin) throws Exception {
        String url = "https://lib-seat.chu.edu.cn/ClientWeb/pro/page/image.aspx?";
        Tesseract tessreact = new Tesseract();
        if (!islogin) {
            url += new Random().nextDouble();
        }
        do {
            CloseableHttpResponse getImgRes = HttpClientConn.getGetRes(url, false, httpClient);
            InputStream content = getImgRes.getEntity().getContent();
            BufferedImage img = ImageIO.read(content);
            ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
            ImageIO.write(cleanColor(img.getSubimage(6, 4, 50, 15)), "JPEG", outputStream);
            ByteArrayInputStream dang = new ByteArrayInputStream(outputStream.toByteArray());
            String result = tessreact.doOCR(ImageIO.read(dang));
            String res = result.replace(" ", "").trim().replaceAll("[^a-zA-Z0-9]", "");
            if (res.length() == 4) {
                return res;
            }
        } while (true);
    }


    public static void test(CloseableHttpClient httpClient, boolean islogin) throws Exception {
//        CloseableHttpResponse getImgRes = HttpClientConn.getGetRes("https://lib-seat.chu.edu.cn/ClientWeb/pro/page/image.aspx?",
//                false, HttpClientConn.getHttpClient());
//        InputStream content = getImgRes.getEntity().getContent();
//        BufferedImage img = ImageIO.read(content);
//        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
//        ImageIO.write(img, "JPEG", outputStream);
//        FileOutputStream fileOutputStream = new FileOutputStream("G:\\project\\libs\\src\\main\\resources\\img\\1.jpeg");
//        fileOutputStream.write(outputStream.toByteArray());
//        outputStream = new ByteArrayOutputStream();
//        ImageIO.write(cleanColor(img.getSubimage(6, 4, 48, 15)), "JPEG", outputStream);
//        fileOutputStream = new FileOutputStream("G:\\project\\libs\\src\\main\\resources\\img\\2.jpeg");
//        fileOutputStream.write(outputStream.toByteArray());
//        Tesseract tessreact = new Tesseract();
//        tessreact.setDatapath(TESSDATA_PATH);
//        ByteArrayInputStream dang = new ByteArrayInputStream(outputStream.toByteArray());
//        String result = tessreact.doOCR(ImageIO.read(dang));
//        String res = result.replace(" ", "").trim();
//        System.out.println(res);
        String url = "https://lib-seat.chu.edu.cn/ClientWeb/pro/page/image.aspx?";
        Tesseract tessreact = new Tesseract();
        if (!islogin) {
            url += new Random().nextDouble();
        }
        do {
            CloseableHttpResponse getImgRes = HttpClientConn.getGetRes(url, false, httpClient);
            InputStream content = getImgRes.getEntity().getContent();
            BufferedImage img = ImageIO.read(content);
            ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
            ImageIO.write(cleanColor(img.getSubimage(6, 4, 50, 15)), "JPEG", outputStream);
            ByteArrayInputStream dang = new ByteArrayInputStream(outputStream.toByteArray());
            BufferedImage t = ImageIO.read(dang);
            write2disk(t,"test");
            String result = tessreact.doOCR(ImageIO.read(dang));
            String res = result.replace(" ", "").trim().replaceAll("[^a-zA-Z0-9]", "");
            if (res.length() == 4) {
                System.out.println(res);
            }
        } while (true);
    }

    public static BufferedImage cleanColor(BufferedImage image) {
        //获取图片的高宽
        int width = image.getWidth();
        int height = image.getHeight();
        //循环执行除去干扰像素
        for (int i = 1; i < width; i++) {
            for (int y = 0; y < height; y++) {
                for (int x = 0; x < width; x++) {
                    Color color = new Color(image.getRGB(x, y));
                    if (color.getRed() > 130 && color.getGreen() > 130 && color.getBlue() > 140) {
                        image.setRGB(x, y, Color.WHITE.getRGB());
                    } else if (color.getRed() == color.getGreen() || color.getBlue() == color.getGreen() || color.getRed() == color.getGreen()) {
                        image.setRGB(x, y, Color.WHITE.getRGB());
                    } else if (color.getBlue() < 40) {
                        image.setRGB(x, y, Color.WHITE.getRGB());
                    }
                }
            }
        }
        //循环执行除去干扰像素
        for (int i = 1; i < width; i++) {
            for (int y = 0; y < height; y++) {
                for (int x = 0; x < width; x++) {
                    Color color = new Color(image.getRGB(x, y));
                    if (color.getRed() == color.getGreen() || color.getBlue() == color.getGreen() || color.getRed() == color.getGreen()) {
                        image.setRGB(x, y, Color.WHITE.getRGB());
                    }
                }
            }
        }
        return denoise(image);
    }


    /**
     * 降噪，以1个像素点为单位（实际使用中可以循环降噪，或者把单位可以扩大为多个像素点）
     */
    public static BufferedImage denoise(BufferedImage image) {
        int width = image.getWidth();
        int height = image.getHeight();
        int white = new Color(255, 255, 255).getRGB();

        if (isWhite(new Color(image.getRGB(1, 0))) && isWhite(new Color(image.getRGB(0, 1)))
                && isWhite(new Color(image.getRGB(1, 1)))) {
            image.setRGB(0, 0, white);
        }
        if (isWhite(new Color(image.getRGB(width - 2, 0))) && isWhite(new Color(image.getRGB(width - 1, 1)))
                && isWhite(new Color(image.getRGB(width - 2, 1)))) {
            image.setRGB(width - 1, 0, white);
        }
        if (isWhite(new Color(image.getRGB(0, height - 2))) && isWhite(new Color(image.getRGB(1, height - 1)))
                && isWhite(new Color(image.getRGB(1, height - 2)))) {
            image.setRGB(0, height - 1, white);
        }
        if (isWhite(new Color(image.getRGB(width - 2, height - 1))) && isWhite(new Color(image.getRGB(width - 1, height - 2)))
                && isWhite(new Color(image.getRGB(width - 2, height - 2)))) {
            image.setRGB(width - 1, height - 1, white);
        }
        int size = 0;
        for (int x = 1; x < width - 1; x++) {
            int y = 0;
            if (isBlack(new Color(image.getRGB(x, y)))) {

                if (isWhite(new Color(image.getRGB(x - 1, y)))) {
                    size++;
                }
                if (isWhite(new Color(image.getRGB(x + 1, y)))) {
                    size++;
                }
                if (isWhite(new Color(image.getRGB(x, y + 1)))) {
                    size++;
                }
                if (isWhite(new Color(image.getRGB(x - 1, y + 1)))) {
                    size++;
                }
                if (isWhite(new Color(image.getRGB(x + 1, y + 1)))) {
                    size++;
                }
                if (size >= 4) {
                    image.setRGB(x, y, white);
                }
            }
        }
        for (int x = 1; x < width - 1; x++) {
            int y = height - 1;
            if (isBlack(new Color(image.getRGB(x, y)))) {
                size = 0;
                if (isWhite(new Color(image.getRGB(x - 1, y)))) {
                    size++;
                }
                if (isWhite(new Color(image.getRGB(x + 1, y)))) {
                    size++;
                }
                if (isWhite(new Color(image.getRGB(x, y - 1)))) {
                    size++;
                }
                if (isWhite(new Color(image.getRGB(x + 1, y - 1)))) {
                    size++;
                }
                if (isWhite(new Color(image.getRGB(x - 1, y - 1)))) {
                    size++;
                }
                if (size >= 4) {
                    image.setRGB(x, y, white);
                }
            }
        }

        for (int y = 1; y < height - 1; y++) {
            int x = 0;
            if (isBlack(new Color(image.getRGB(x, y)))) {
                size = 0;
                if (isWhite(new Color(image.getRGB(x + 1, y)))) {
                    size++;
                }
                if (isWhite(new Color(image.getRGB(x, y + 1)))) {
                    size++;
                }
                if (isWhite(new Color(image.getRGB(x, y - 1)))) {
                    size++;
                }
                if (isWhite(new Color(image.getRGB(x + 1, y - 1)))) {
                    size++;
                }
                if (isWhite(new Color(image.getRGB(x + 1, y + 1)))) {
                    size++;
                }
                if (size >= 4) {
                    image.setRGB(x, y, white);
                }
            }
        }

        for (int y = 1; y < height - 1; y++) {
            int x = width - 1;
            if (isBlack(new Color(image.getRGB(x, y)))) {
                size = 0;
                if (isWhite(new Color(image.getRGB(x - 1, y)))) {
                    size++;
                }
                if (isWhite(new Color(image.getRGB(x, y + 1)))) {
                    size++;
                }
                if (isWhite(new Color(image.getRGB(x, y - 1)))) {
                    size++;
                }
                //斜上下为空时，去掉此点
                if (isWhite(new Color(image.getRGB(x - 1, y + 1)))) {
                    size++;
                }
                if (isWhite(new Color(image.getRGB(x - 1, y - 1)))) {
                    size++;
                }
                if (size >= 5) {
                    image.setRGB(x, y, white);
                }
            }
        }

        //降噪，以1个像素点为单位
        for (int y = 1; y < height - 1; y++) {
            for (int x = 1; x < width - 1; x++) {
                if (isBlack(new Color(image.getRGB(x, y)))) {
                    size = 0;
                    //上下左右均为空时，去掉此点
                    if (isWhite(new Color(image.getRGB(x - 1, y)))) {
                        size++;
                    }
                    if (isWhite(new Color(image.getRGB(x + 1, y)))) {
                        size++;
                    }
                    //上下均为空时，去掉此点
                    if (isWhite(new Color(image.getRGB(x, y + 1)))) {
                        size++;
                    }
                    if (isWhite(new Color(image.getRGB(x, y - 1)))) {
                        size++;
                    }
                    //斜上下为空时，去掉此点
                    if (isWhite(new Color(image.getRGB(x - 1, y + 1)))) {
                        size++;
                    }
                    if (isWhite(new Color(image.getRGB(x + 1, y - 1)))) {
                        size++;
                    }
                    if (isWhite(new Color(image.getRGB(x + 1, y + 1)))) {
                        size++;
                    }
                    if (isWhite(new Color(image.getRGB(x - 1, y - 1)))) {
                        size++;
                    }
                    if (size >= 7) {
                        image.setRGB(x, y, Color.WHITE.getRGB());
                    }
                }
            }
        }
        return image;
    }

    public static boolean isBlack(Color color) {
        return color.getRed() + color.getGreen() + color.getBlue() <= 580 || color.getBlue() > 205 || color.getRed() > 190;
    }

    public static boolean isWhite(Color color) {
        return color.getRed() + color.getGreen() + color.getBlue() > 680;
    }


}
